/*
 *  Copyright 2012 Zdeněk Janeček

 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at

 *    http://www.apache.org/licenses/LICENSE-2.0

 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package kiv.pt.ui;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;

import kiv.pt.DataGuru;
import kiv.pt.PowController;
import kiv.pt.Simulator;

/**
 * Běhová třída.
 * @author Zdeněk Janeček
 */
public class IniTrida {
    private static final int MODE_QUIET = 1;
    private static final int MODE_INTER = 0;
    private static final int PROGRESS = 5;
    private static final int ADDENDUM = 6;

    private static Simulator sim;
    private static PowController cntr;
    private static BufferedWriter sources;
    private static BufferedWriter place;

    private static TUI text;
    private static String msg = null;

    private static int mode = MODE_INTER;
    private static String[][] udaje;
    private static int time = 0;
    private static int iniTime;
    
    private IniTrida() {
        // Nepoužívá se
    }
    
    /**
     * @param args -f název datového souboru; -q jednoduchý mód
     */
    public static void main(String[] args) {
        String file = null;
        for (int i = 0; i < args.length; i++) {
            switch (args[i]) {
            case "-q":
                mode = MODE_QUIET;
                break;
            case "-f":
                file = args[++i];
                break;
            default:
                System.out.print("Neplatný parametr: "+args[i]);
                System.exit(-1);
                break;
            }
        }
        
        if (file == null) {
            System.out.println("Nezadali jste datový soubor");
            System.exit(-1);
        }
        
        try {
            DataGuru.nactiDataSite(file);
            sources = new BufferedWriter(new FileWriter("source_stat.csv"));
            sources.write("Čas;Vytížení hlavní;Vytížení 1.;Vytížení 2.;Vytížení 3.;Vytížení 4.;Vytížení 5.;Vytížení 6.;Vytížení 7.;Vytížení 8.;Vytížení 9.;Vytížení 10.;Spotřebováno;Vyrobeno\n");
        } catch (FileNotFoundException e) {
            System.out.print("Chyba vstupu/výstupu datového souboru");
            return;
        } catch (IOException e) {
            System.out.print("Chyba vstupu/výstupu souboru se statistikou");
            return;
        }
        
        DataGuru.calculateDistances();
        DataGuru.zdroje.get(0).setVykon(PowController.HL_MAX);
        for (int i = 1; i < DataGuru.zdroje.size(); i++) {
            DataGuru.zdroje.get(i).setVykon((int) (PowController.ALT_MAX));
        }

        cntr = new PowController();
        
        if (mode == MODE_INTER) {
            sim = new Simulator();
            text = new TUI(cntr, sim);
            text.changeScreen("Vítejte!", "");
            iniTime = 0;
            text.start();

        } else if (mode == MODE_QUIET) {
            System.out.println("Zadejte počet opakování pak počáteční čas.");
            int count = 0;
            int time = 0;
            try {
                BufferedReader br = new BufferedReader(new InputStreamReader(
                        System.in));
                count = Integer.parseInt(br.readLine());
                time = Integer.parseInt(br.readLine());
                br.close();
            } catch (IOException e) {
                System.out.println("Nezadali jste číslo");
            }
            iniTime = time;
            sim = new Simulator(count, time);
        }

        cntr.calcNetworkStart();
        
        udaje = new String[DataGuru.mista.size()][24];
        for (int i = 0; i < udaje.length; i++) {
            udaje[i][0] = "Místo "+i;
        }
        
        sim.start();

        // sim.setTime(16);

        // příklad přístupu
        // for (int i = 0; i < DataGuru.mista.size(); i++) {
        // System.out.println(DataGuru.mista.get(i).getPrikon());
        // }
    }

    /**
     * Vypíše řetězec na správné místo.
     * 
     * @param s Řetězec k výpisu.
     */
    public static synchronized void setReport(String s) {
        cntr.calcZateze();
        sim.calculateFuture();
        cntr.regulujVykon(sim);

        sourceStats();
        try {
            placeStats(PROGRESS);
        } catch (IOException e) {
            System.out.print("Chyba při zápisu do souboru statistik míst");
        }
        
        time++;
        
        if (mode == MODE_INTER) {
            text.changeScreen(s, msg);
            msg = "";
        } else if (mode == MODE_QUIET) {
            System.out.println(s);
            if (msg != null) {
                System.out.println(" ## " + msg);
            }
        }

        msg = null;
    }

    /**
     * Slouží k vypsání chybové hlášky na obrazovku.
     * 
     * @param send zpráva, která se vytiskne červeně.
     */
    public static synchronized void errorMessage(String send) {
        msg = send;
    }

    private static void placeStats(int type) throws IOException {
        if (type == PROGRESS) {
            for (int i = 0; i < DataGuru.mista.size(); i++) {
                double prikon = DataGuru.mista.get(i).getPrikon();
                cntr.mistaCelk[i] += prikon;
                udaje[i][time + 1] = String.format("%.2f", prikon);
                
                double price = cntr.suppliers[i] == 0 ? PowController.PRICE_MAIN : PowController.PRICE_ALT;
                cntr.cenaCelk[i] += price * prikon;
            }
        } else if (type == ADDENDUM) {
            place = new BufferedWriter(new FileWriter("place_stat.csv"));
            
            place.write("Čas");
            for (int i = 0; i < time; i++) {
                place.write(String.format(";%d", i+iniTime));
            }
            place.write(";Spotřeboval;Zaplatí\n");
            for (int i = 0; i < udaje.length; i++) {
                for (int j = 0; j < time + 1; j++) {
                    place.write(udaje[i][j]+";");
                }
                place.write(String.format("%.2f;%.2f\n", cntr.mistaCelk[i], cntr.cenaCelk[i]));
            }
            
            place.close();
        }
    }
    
    private static void sourceStats() {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < cntr.zateze.length; i++) {
            sb.append(String.format(";%.2f", cntr.zateze[i]));
        }
        String time = String.format("%d", sim.getTime());
        String zat = sb.toString();
        
        int used = 0;
        for (int i = 0; i < DataGuru.mista.size(); i++) {
            used += DataGuru.mista.get(i).getPrikon();
        }
        int cr = 0;
        for (int i = 0; i < DataGuru.zdroje.size(); i++) {
            cr += DataGuru.zdroje.get(i).getVykon();
        }
        String ad = ";"+used+";"+cr;
        try {
            sources.write(time+zat+ad+"\n");
        } catch (IOException e) {
            System.out.print("Chyba zápisu do souboru");
        }
    }
    
    /**
     * Provede ukončení běžících vláken.
     */
    public static synchronized void uklid() {
        try {
            System.out.println("\nBy!");
            if (sim.isRunning()) {
                sim.zastav();
                sim.join();
            }
            placeStats(ADDENDUM);
            sources.close();
        } catch (InterruptedException e) {
            System.out.println("Chyba při úklidu");
        } catch (IOException e) {
            System.out.println("Soubor nelze zavřít");
        }
    }
}
